#include "syntax_parser.h"
#include "errors_warnings.h"

#include "main_container.h"
extern MainContainer * CompilerData;

// <method_body_decl> ~ ;  {;}
// <method_body_decl> ~ { <method_body> }  {{}
void Parser::Parse_MethodBodyDecl(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_MethodBodyDecl");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon)
	{
		// write type of production in this node
		parent->Production = Gr_MethodBodyDecl__spSemiCol;

		// process terminal symbol ';' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
	}

	else if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftCurlyBrace )
	{
		// write type of production in this node
		parent->Production = Gr_MethodBodyDecl__spLCBrac_MethodBody_spRCBrac;

		//  process terminal symbol '{' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		//  process nonterminal symbol <method_body> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_MethodBody(newNode1);

		// process terminal symbol '}' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightCurlyBrace )
		{
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			newNode2->LexUnitID=this->CurrentLexicPosition;
			newNode2->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_RIGHT_SQUARE_BRACKET_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}
	}

	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_METHOD_BODY_DECL_BEGINING);
		// MAKE LOGICAL RECOVERING
		this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_MethodBodyDecl");
#endif
}
// <method_body> ~ <label_method_statement> <method_body>  {NAME, if, while, for, do, switch, break, continue, goto, start, stop, derivation, int, float, bool, state, time, void, Facility, Storage, Queue, ADTable, Group, OutputStream, trace, return}
// <method_body> ~ ? {}}
void Parser::Parse_MethodBody(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_MethodBody");
#endif
	
	LexicUnit currentUnit;
	do
	{
		// get current lexic unit
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

		if( (currentUnit.type == LUTypeIdentifier) || 
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordIf) || 
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordWhile) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFor) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordDo) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSwitch) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordBreak) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordContinue) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordGoto) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStart) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStop) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordDerivation) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordInt) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFloat) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordBool) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordState) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordTime) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordVoid) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFacility) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStorage) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordQueue) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordADTable) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordGroup) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordOutputStream)||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordReturn)||
         ( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordTrace)
         )
		{
			// write type of production in this node
			
			parent->Production = Gr_MethodBody__LabelMethodStatement_MethodBody;

			// process nonterminal symbol <label_method_statement> 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			Parse_LabelMethodStatement(newNode0);

		}

		else if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightCurlyBrace )
		{
			// write type of production in this node
			parent->Production = Gr_MethodBody__LabelMethodStatement_MethodBody;
			break;
		}


		else
		{
			// ERROR has been found
			// REPORT ERROR
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_METHOD_BODY_BEGINING);
			// MAKE LOGICAL RECOVERING
			this->CurrentLexicPosition++;
			break;
		}
	}while(1);
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_MethodBody");
#endif
}
// <label_method_statement> ~ <method_labels>  <method_statement>  {NAME, if, while, for, do, switch, break, continue, goto, start, stop, derivation, int, float, bool, state, time, void, Facility, Storage, Queue, ADTable, Group, OutputStream, trace, return, }}
void Parser::Parse_LabelMethodStatement(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_LabelMethodStatement");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if((currentUnit.type == LUTypeIdentifier) || 
		(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightCurlyBrace)||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordIf) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordWhile) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFor) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordDo) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSwitch) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordBreak) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordContinue) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordGoto) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStart) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStop) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordDerivation) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordInt) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFloat) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordBool) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordState) ||		
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordTime) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordVoid) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFacility) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStorage) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordQueue) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordADTable) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordGroup) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordOutputStream)||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordReturn)||
      ( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordTrace)
      )
	{
		// write type of production in this node
		parent->Production = Gr_LabelMethodStatement__MethodLabels_MethodStatement;

		// process nonterminal symbol <method_labels>  
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_MethodLabels(newNode0);

		// process nonterminal symbol <method_statement> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_MethodStatement(newNode1);
	}


	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_LABEL_METHOD_STATEMENT_BEGINING);
		// MAKE LOGICAL RECOVERING
		this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_LabelMethodStatement");
#endif
}



// <namespace_definition> ~ namespace <name> { <using_directives> <file_body> }  {namespace}
// <method_statements> ~ <method_statement> <method_statements>  {if, while, for, do, switch, break, continue, goto, start, stop, derivation, int, float, bool, state, time, void, Facility, Storage, Queue, ADTable, Group, OutputStream, NAME, trace}
// <method_statements> ~ ? {}}

/*
void Parser::Parse_MethodStatements(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_MethodStatements");
#endif
	LexicUnit currentUnit;
	do 
	{
		// get current lexic unit
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

		if((currentUnit.type == LUTypeIdentifier) || 
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordIf) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordWhile) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFor) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordDo) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSwitch) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordBreak) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordContinue) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordGoto) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStart) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStop) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordDerivation) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordInt) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFloat) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordBool) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordState) ||		
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordTime) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordVoid) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFacility) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStorage) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordQueue) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordADTable) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordGroup) ||
			( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordOutputStream)||
         ( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordTrace))
		{
			// write type of production in this node
			parent->Production = Gr_MethodStatements__MethodStatement_MethodStatements;

			// process nonterminal symbol <method_statement> 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			Parse_MethodStatement(newNode0);

		}

		else if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightCurlyBrace )
		{
			// write type of production in this node
			parent->Production = Gr_MethodStatements__MethodStatement_MethodStatements;
			break;
		}


		else
		{
			// ERROR has been found
			// REPORT ERROR
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_METHOD_STATEMENTS_BEGINING);
			// MAKE LOGICAL RECOVERING
			this->CurrentLexicPosition++;
			break;
		}
	}while(1);
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_MethodStatements");
#endif
}

*/




void Parser::Parse_NamespaceDefinition(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_NamespaceDefinition");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNamespace )
	{
		// write type of production in this node
		parent->Production = Gr_NamespaceDefinition__namespace_Name_spLCBrac_UsingDirectives_FileBody_spRCBrac;

		// process terminal symbol 'namespace' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <name> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Name(newNode1);

		// process terminal symbol '{' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftCurlyBrace )
		{
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			newNode2->LexUnitID=this->CurrentLexicPosition;
			newNode2->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_LEFT_CURLY_BRACE_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

		// process nonterminal symbol <using_directives> 
		SyntaxTreeNode * newNode3 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode3);
		Parse_UsingDirectives(newNode3);

		// process nonterminal symbol <file_body> 
		SyntaxTreeNode * newNode4 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode4);
		Parse_FileBody(newNode4);

		// process terminal symbol '}' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightCurlyBrace )
		{
			SyntaxTreeNode * newNode5 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode5);
			newNode5->LexUnitID=this->CurrentLexicPosition;
			newNode5->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_LEFT_CURLY_BRACE_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}


	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_NAMESPACE_DEFINITION_BEGINING);
		// MAKE LOGICAL RECOVERING
		this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_NamespaceDefinition");
#endif
}
// <parameters> ~ <parameter> <parameters_add>  {int, float, bool, state, time, void, Facility, Storage, Queue, ADTable, Group, OutputStream, NAME}
// <parameters> ~ ? {)}
void Parser::Parse_Parameters(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_Parameters");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( (currentUnit.type == LUTypeIdentifier) || 
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordInt) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFloat) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordBool) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordState) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordTime) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordVoid) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFacility) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStorage) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordQueue) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordADTable) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordGroup) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordOutputStream) )
	{
		// write type of production in this node
		parent->Production = Gr_Parameters__Parameter_ParametersAdd;

		// process nonterminal symbol <parameter> 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_Parameter(newNode0);

		// process nonterminal symbol <parameters_add> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_ParametersAdd(newNode1);

	}

	else if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightParenthesis )
	{
		// write type of production in this node
		parent->Production = Gr_Parameters__epsilon;
	}


	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_PARAMETERS_BEGINING);
		// MAKE LOGICAL RECOVERING
		this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Parameters");
#endif
}
// <parameter_comma_add> ~ , <parameter>  {,}
void Parser::Parse_ParameterCommaAdd(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_ParameterCommaAdd");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterComma ) 
	{
		// write type of production in this node
		parent->Production = Gr_ParameterCommaAdd__spComma_Parameter;

		// process terminal symbol ',' 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			newNode0->LexUnitID=this->CurrentLexicPosition;
			newNode0->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		// process nonterminal symbol <parameter> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Parameter(newNode1);

	}


	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_PARAMETER_COMMA_ADD_BEGINING);
		// MAKE LOGICAL RECOVERING
		this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_ParameterCommaAdd");
#endif
}
// <parameters_add> ~ <parameter_comma_add> <parameters_add>  {,}
// <parameters_add> ~ ? {)}
void Parser::Parse_ParametersAdd(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_ParametersAdd");
#endif
	LexicUnit currentUnit;
	do
	{
		// get current lexic unit
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

		if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterComma )
		{
			// write type of production in this node
			parent->Production = Gr_ParametersAdd__ParameterCommaAdd_ParametersAdd;

			// process nonterminal symbol <parameter_comma_add> 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			Parse_ParameterCommaAdd(newNode0);

		}

		else if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightParenthesis )
		{
			// write type of production in this node
			parent->Production = Gr_ParametersAdd__ParameterCommaAdd_ParametersAdd;
			break;

		}


		else
		{
			// ERROR has been found
			// REPORT ERROR
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_PARAMETERS_ADD_BEGINING);
			// MAKE LOGICAL RECOVERING
			this->CurrentLexicPosition++;
			break;
		}
	}while(1);
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_ParametersAdd");
#endif
}
// <parameter> ~ <data_type> NAME <array_definitions>   {int, float, bool, state, time, void, Facility, Storage, Queue, ADTable, Group, OutputStream, NAME}
void Parser::Parse_Parameter(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_Parameter");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( (currentUnit.type == LUTypeIdentifier) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordInt) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFloat) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordBool) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordState) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordTime) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordVoid) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFacility) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStorage) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordQueue) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordADTable) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordGroup) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordOutputStream) )
	{
		// write type of production in this node
		parent->Production = Gr_Parameter__DataType_NAME_ArrayDefinitions;

		// process nonterminal symbol <data_type> 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_DataType(newNode0);

		// process terminal symbol 'NAME' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeIdentifier )
		{
			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_NAME_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

		// process nonterminal symbol <array_definitions> 
		SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode2);
		Parse_ArrayDefinitions(newNode2);

	}

	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_PARAMETER_BEGINING);
		// MAKE LOGICAL RECOVERING
		this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Parameter");
#endif
}
// <arguments> ~ <expression> <arguments_add>  {!, -, +, (, LITERAL, null, new, NAME}
// <arguments> ~ ? {)}
void Parser::Parse_Arguments(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_Arguments");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( (currentUnit.type == LUTypeIdentifier) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNull) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordNew) ||
		(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorNot) ||
		(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorNegation) ||
		(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorAddition) ||
		(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftParenthesis) ||
		(currentUnit.type == LUTypeConstantBool)  || (currentUnit.type == LUTypeConstantFloat) ||
		(currentUnit.type == LUTypeConstantInteger) )
	{
		// write type of production in this node
		parent->Production = Gr_Arguments__Expression_ArgumentsAdd;

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_Expression(newNode0);

		// process nonterminal symbol <arguments_add> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_ArgumentsAdd(newNode1);

	}

	else if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightParenthesis )
	{
		// write type of production in this node
		parent->Production = Gr_Arguments__epsilon;
	}
	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_ARGUMENTS_BEGINING);
		// MAKE LOGICAL RECOVERING
		this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Arguments");
#endif
}

// <arguments_add> ~ <argument_comma_add> <arguments_add>  {,}
// <arguments_add> ~ ? {)}
void Parser::Parse_ArgumentsAdd(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_ArgumentsAdd");
#endif
	LexicUnit currentUnit;
	do 
	{
		// get current lexic unit
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

		if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterComma )
		{
			// write type of production in this node
			parent->Production = Gr_ArgumentsAdd__ArgumentCommaAdd_ArgumentsAdd;

			// process nonterminal symbol <argument_comma_add> 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			Parse_ArgumentCommaAdd(newNode0);

		}

		else if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightParenthesis ) 
		{
			// write type of production in this node
			parent->Production = Gr_ArgumentsAdd__ArgumentCommaAdd_ArgumentsAdd;
			break;
		}


		else
		{
			// ERROR has been found
			// REPORT ERROR
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_ARGUMENTS_ADD_BEGINING);
			// MAKE LOGICAL RECOVERING
			this->CurrentLexicPosition++;
			break;
		}
	}while(1);
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_ArgumentsAdd");
#endif
}
// <argument_comma_add> ~ , <expression>  {,}
void Parser::Parse_ArgumentCommaAdd(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_ArgumentCommaAdd");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterComma )
	{
		// write type of production in this node
		parent->Production = Gr_ArgumentCommaAdd__spComma_Expression;


		// process terminal symbol ',' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression(newNode1);
	}


	else
	{
		// ERROR has been found
		// REPORT ERROR
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_ARGUMENT_COMMA_ADD_BEGINING);
		// MAKE LOGICAL RECOVERING
		this->CurrentLexicPosition++;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_ArgumentCommaAdd");
#endif
}
/*
void Parser::Parse_Label(SyntaxTreeNode * parent)
{
}*/
/*
void Parser::Parse_MethodStatement(SyntaxTreeNode * parent)
{
}
*/
/*
void Parser::Parse_UsingDirectives(SyntaxTreeNode * parent)
{
}
void Parser::Parse_FileBody(SyntaxTreeNode * parent)
{
}*/

